﻿using System;
using System.Collections.Generic;
using System.Text;

namespace SBToolkit.Collections
{
    /// <summary>
    /// Extends <see cref="IEnumerable{T}"/> with additional functionality.
    /// </summary>
    public static class EnumerableHelper
    {
        /// <summary>
        /// Concatenates specified items.
        /// </summary>
        /// <typeparam name="T">Type of items to concatenate.</typeparam>
        /// <param name="items">Items to concatenate.</param>
        /// <param name="separator">The separator.</param>
        /// <returns>Concatenated string.</returns>
        public static string Concatenate<T>(this IEnumerable<T> items, string separator)
        {
            return items.Concatenate(item => item.ToString(), separator);
        }

        /// <summary>
        /// Concatenates specified items.
        /// </summary>
        /// <typeparam name="T">Type of items to concatenate.</typeparam>
        /// <param name="items">Items to concatenate.</param>
        /// <param name="func">Function to use for concatenation.</param>
        /// <param name="separator">The separator.</param>
        /// <returns>Concatenated string.</returns>
        public static string Concatenate<T>(this IEnumerable<T> items, Func<T, string> func, string separator)
        {
            var sb = new StringBuilder();

            foreach (var item in items)
            {
                sb.Append(func(item));
                sb.Append(separator);
            }

            return sb.Remove(sb.Length - separator.Length, separator.Length).ToString();
        }

        /// <summary>
        /// Enumerates over all items and executes specified action.
        /// </summary>
        /// <typeparam name="T">The type of items to enumerate.</typeparam>
        /// <param name="items">Items to operate on.</param>
        /// <param name="action">Action to execute for each item.</param>
        public static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
        {
            foreach (var item in items)
            {
                action(item);
            }
        }

    }
}
